﻿using System;
using Framework;
using Game.Lua.Base;
using UnityEngine;
using UnityEngine.UI;
using XLua;
using Object = System.Object;

namespace Game.Lua.UI
{

    [System.Serializable]
    public class Injection
    {
        public string name;
        public GameObject value;
    }

    public class LuaUIFormLogic : UIFormLogic 
    {
        
        public string luaAssetName;
        public Injection[] injections;

        // internal static LuaEnv luaEnv = new LuaEnv(); //all lua behaviour shared one luaenv only!
        // internal static float lastGCTime = 0;
        // internal const float GCInterval = 1;//1 second 

        private Action luaStart;
        private Action luaUpdate;
        private Action luaOnDestroy;
        
        private Action<LuaTable,Object> luaOnInit;
        private Action<LuaTable,Object> luaOnOpen;
        private Action<LuaTable,Object> luaOnClose;
        private Action<LuaTable,Object> luaOnRecycle;
        private Action<LuaTable,float,float,Object> luaOnUpdate;
        
        LuaTable m_table;
        private LuaTable scriptEnv;

        // private LuaManager m_luaManager;
        void Start()
        {
            if (luaStart != null)
            {
                luaStart();
            }
        }

        LuaTable GetUiFormTable()
        {
            var m_luaManager = GameEntry.GetComponent<LuaManager>();
            scriptEnv = m_luaManager.CreatNewLuaScriptEnv();
            
            m_luaManager.DoString($"local type= require 'ui.uiform_class.{luaAssetName}' Obj=type.new()",$"uiform.{this.UIForm.SerialId}",scriptEnv);
            // m_luaManager.DoString($"local type = require 'ui.uiform.{luaAssetName}' Obj=type.new()", $"UIForm.{this.UIForm.SerialId}",scriptEnv);
            LuaTable table;
            scriptEnv.Get("Obj",out table);
            return table;
        }
        protected internal override void OnInit(object userData)
        {
            base.OnInit(userData);
            // Button b = null;
            // b.onClick.RemoveAllListeners();
            
        //    return;

            m_table=GetUiFormTable();

            
            
            foreach (var injection in injections)
            {
                m_table.Set(injection.name, injection.value);
            }

            m_table.Set("uiLogic", this);
            
            m_table.Get("start", out luaStart);
            m_table.Get("update", out luaUpdate);
            m_table.Get("onDestroy", out luaOnDestroy);
            m_table.Get("onInit", out luaOnInit);
            m_table.Get("onOpen", out luaOnOpen);
            m_table.Get("onClose", out luaOnClose);
            m_table.Get("onRecycle", out luaOnRecycle);
            m_table.Get("onUpdate", out luaOnUpdate);
            
            
            
            
            luaOnInit?.Invoke(m_table,userData);
        }

        public override void OnOpen(object userData)
        {
            base.OnOpen(userData);
            luaOnOpen?.Invoke(m_table,userData);
        }

        public override void OnClose(object userData)
        {
            base.OnClose(userData);
            luaOnClose?.Invoke(m_table,userData);
        }

        public override void OnRecycle(object userData)
        {
            luaOnRecycle?.Invoke(m_table,userData);
        }

        public override void OnUpdate(float elapseSeconds, float realElapseSeconds, object userData)
        {
            luaOnUpdate?.Invoke(m_table,elapseSeconds,realElapseSeconds,userData);
        }

        public void OnDestroy()
        {
            if (luaOnDestroy != null)
            {
                luaOnDestroy();
            }
            luaOnDestroy = null;
            luaUpdate = null;
            luaStart = null;
            luaOnInit= null;
            luaOnOpen= null;
            luaOnClose= null;
            luaOnRecycle= null;
            luaOnUpdate= null;
            m_table?.Dispose();
            scriptEnv.Dispose();
            injections = null;
        }
    }
    

}